/**
 * 
 */
package fluo.desktopserver;

import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;

import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;

import java.util.ArrayList;
import java.util.HashMap;

import fluo.centralserver.CentralServerDetails;
import fluo.centralserver.RegisterDesktop;

/**
 * @author maherbeg
 *
 * Created: Apr 11, 2009
 * Modified: Apr 11, 2009
 */
public class DesktopServer extends WindowAdapter implements CentralServerDetails, Runnable, ActionListener {

	RegisterDesktop ServerDetails;
	HashMap<String, ArrayList<String>> MusicList; //Key = Parent Directory, Value = List of mp3 files under the directory
	
	//GUI Details
	JFrame MainWindow;
	JButton AddFolder;
	JButton RemoveFolder;
	JList FolderList;
	JLabel StatusBar;
	DefaultListModel FolderListModel;
	JFileChooser chooser;
	
	private boolean debug = true;
	
	/* (non-Javadoc)
	 * @see java.lang.Runnable#run()
	 */
	public void run() {
		// TODO Auto-generated method stub
		//Now send off our details to the CentralServer
		try {
			Socket register = new Socket(InetAddress.getByName(CentralServerDetails.ip),CentralServerDetails.port);
			
			ObjectOutputStream oos = new ObjectOutputStream(register.getOutputStream());
			ObjectInputStream ois = new ObjectInputStream(register.getInputStream());
			
			oos.writeObject(ServerDetails);
			
			Object receiveData = ois.readObject();
			
			if(receiveData != null){
				if(receiveData instanceof RegisterDesktop){
					ServerDetails = (RegisterDesktop)receiveData;
					if(!ServerDetails.isAccepted()){
						//TODO Deal with unaccepted Server Details
					}
				}
			}
			
			register.close();
		} catch (UnknownHostException e) {
			System.out.println("DesktopServer.DesktopServer(): Can not find the Central Server, check to see if it is running.");
			e.printStackTrace();
		} catch (IOException e) {
			System.out.println("DesktopServer.DesktopServer(): Issue with input/output system");
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			System.out.println("DesktopServer.DesktopServer(): Incorrect object sent over stream.");
			e.printStackTrace();
		}

	}
	
	public DesktopServer(){
		ServerDetails = new RegisterDesktop(
										JOptionPane.showInputDialog("Please select a name for your server."),
										"localhost", 42425);
		
			
			MusicList = new HashMap<String, ArrayList<String>>();
			
			//We have registered our selves to the main server, let us set up our GUI
			MainWindow = new JFrame("Fluo Music Server - " + ServerDetails);
			MainWindow.addWindowListener((WindowListener) this);
			MainWindow.setSize(400,400);
			
			JPanel content = new JPanel(new GridBagLayout());
			GridBagConstraints gbc = new GridBagConstraints();
			gbc.fill = GridBagConstraints.HORIZONTAL;
			gbc.weightx = 0.5;
			
			//TODO Add Icons for the buttons
			
			gbc.gridx = 0; gbc.gridy = 0;
			AddFolder = new JButton("Add Folder");
			AddFolder.setActionCommand("Add Folder"); AddFolder.addActionListener(this);
			AddFolder.setMnemonic(KeyEvent.VK_A);
			content.add(AddFolder, gbc);
			
			gbc.gridx = 1; gbc.gridy = 0;
			RemoveFolder = new JButton("Remove Folder");
			RemoveFolder.setActionCommand("Remove Folder"); RemoveFolder.addActionListener(this);
			RemoveFolder.setMnemonic(KeyEvent.VK_R);
			content.add(RemoveFolder,gbc);
			
			gbc.gridx = 0; gbc.gridy =1; gbc.gridwidth=2; gbc.weighty = 1.0;
			FolderListModel = new DefaultListModel(); FolderList = new JList(FolderListModel);
			FolderList.setSize(400, 600);
			FolderList.setVisible(true);
			FolderList.setVisibleRowCount(10);
			JScrollPane FolderScroll = new JScrollPane(FolderList);
			content.add(FolderScroll, gbc);
			
			gbc.gridx = 0; gbc.gridy = 2; gbc.gridwidth=2;
			StatusBar = new JLabel("Ready to serve files.");
			StatusBar.setSize(400, 25);
			content.add(StatusBar, gbc);
			
			MainWindow.add(content);
			MainWindow.setVisible(true);
			//Start our main thread
			Thread t= new Thread(this);
			t.start();
	}
	
	public void windowClosing(WindowEvent we){
		MainWindow.dispose();
	}

	public void actionPerformed(ActionEvent e) {
		if(e.getActionCommand().equals("Add Folder")){
			if(debug) System.out.println("DesktopServer.actionPerformed(Adding folder)");
			chooser = new JFileChooser();
		    chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
		    chooser.setMultiSelectionEnabled(false);
			
			int retVal = chooser.showOpenDialog(MainWindow);
			if(retVal == JFileChooser.APPROVE_OPTION){
				if(debug) System.out.println("Desktop.actionPerformed(Adding Folder): Approved the selection of " + chooser.getSelectedFile());
				new FolderScanner(this,chooser.getSelectedFile());
			}
			
		} else if(e.getActionCommand().equals("Remove Folder")){
			if(debug) System.out.println("DesktopServer.actionPerformed(Removing folder)");
			if(FolderList.getSelectedIndices() != null){
				int remove[] = FolderList.getSelectedIndices();
				for(int i=remove.length-1; i >= 0; i--){
					if(debug) System.out.println("DesktopServer.actionPerformed(Removing Folder): Index to remove " + i);
					String toRemove = (String)FolderListModel.get(remove[i]).toString();
					setMessage("Removing " + toRemove);
					MusicList.remove(toRemove);
					FolderListModel.removeElementAt(remove[i]);
					setMessage("Removed " + toRemove);
					//TODO Scan file list and remove anything under this folder
				}
			}
		}
	}
	
	public void setMessage(String status){
		StatusBar.setText(status);
	}
	
	public HashMap<String, ArrayList<String>> getMusicList(){
		return MusicList;
	}
	
	public boolean getDebug(){
		return debug;
	}
	
	public void addFolder(String folderName, ArrayList<String> folderList){
		MusicList.put(folderName, folderList);
		FolderListModel.addElement(chooser.getSelectedFile());
	}
}
